package com.congwulin.wechat.util.service.bill;

import com.congwulin.wechat.entity.common.AbstractMeBillVO;
import com.congwulin.wechat.entity.common.SuperVO;
import com.congwulin.wechat.util.EntityConst;

import java.util.*;

/**
 * 单据工具
 */
public class BillTool {


    /**
     * 将原始单据上的时间戳复制到目的单据上
     *
     * @param origin 原始单据
     * @param target 目的单据
     */
    public void copyTs(AbstractMeBillVO origin, AbstractMeBillVO target) {
        SuperVO head = origin.getHead();
        target.getHead().setTs(head.getTs());

        Map<String, Class<?>> areaIndex = origin.getAreaNameIndex();
        Set<Map.Entry<String, Class<?>>> set = areaIndex.entrySet();
        for (Map.Entry<String, Class<?>> entry : set) {
            Class<?> clazz = entry.getValue();
            List<SuperVO> childlist = origin.getChildren(clazz);
            Map<String, SuperVO> index = new HashMap<String, SuperVO>();
            if (childlist == null) {
                continue;
            }
            for (SuperVO vo : childlist) {
                index.put(vo.getId(), vo);
            }
            childlist = origin.getChildren(clazz);
            if (childlist == null) {
                continue;
            }
            for (SuperVO vo : childlist) {
                SuperVO originvo = index.get(vo.getId());
                if (originvo != null) {
                    vo.setTs(originvo.getTs());
                }
            }
        }
    }

    /**
     * 将原始单据上的时间戳复制到目的单据上
     *
     * @param originlist 原始单据列表
     * @param targetlist 目的单据列表
     */
    public void copyTs(List<AbstractMeBillVO> originlist, List<AbstractMeBillVO> targetlist) {
        Map<String, AbstractMeBillVO> index = new HashMap<String, AbstractMeBillVO>();
        for (AbstractMeBillVO bill : originlist) {
            SuperVO head = bill.getHead();
            index.put(head.getId(), bill);
        }
        for (AbstractMeBillVO bill : targetlist) {
            SuperVO head = bill.getHead();
            AbstractMeBillVO origin = index.get(head.getId());
            if (origin == null) {
                continue;
            }
            this.copyTs(origin, bill);
        }
    }

    /**
     * 将单据上的删除行过滤掉
     *
     * @param list 过滤后的单据
     */
    public void fileterBillDeleteRow(List<AbstractMeBillVO> list) {
        for (AbstractMeBillVO bill : list) {
            this.fileterBillDeleteRow(bill);
        }
    }

    /**
     * 根据实体的状态对实体进行分组
     *
     * @param list 单据列表
     * @param status 实体状态
     * @return 实体类与实体列表的映射
     */
    public Map<Class<?>, List<SuperVO>> group(List<AbstractMeBillVO> list, int status) {
        Map<Class<?>, List<SuperVO>> index = new HashMap<Class<?>, List<SuperVO>>();
        for (AbstractMeBillVO bill : list) {
            Map<Class<?>, List<SuperVO>> voIndex = this.group(bill, status);
            // 实现批量插入
            for (Class<?> key : voIndex.keySet()) {
                if (index.containsKey(key)) {
                    index.get(key).addAll(voIndex.get(key));
                } else {
                    index.put(key, voIndex.get(key));
                }
            }

        }
        return index;
    }

    /**
     * 设置单据上所有实体的状态
     *
     * @param list 单据类表
     * @param status 实体状态
     */
    public void setStatus(List<AbstractMeBillVO> list, int status) {
        for (AbstractMeBillVO bill : list) {
            this.setStatus(bill, status);
        }
    }

    private void fileterBillDeleteRow(AbstractMeBillVO bill) {
        Map<String, Class<?>> areaIndex = bill.getAreaNameIndex();
        Set<Map.Entry<String, Class<?>>> set = areaIndex.entrySet();
        for (Map.Entry<String, Class<?>> entry : set) {
            Class<?> clazz = entry.getValue();
            List<SuperVO> childlist = bill.getChildren(clazz);
            List<SuperVO> volist = new ArrayList<SuperVO>();
            if (childlist != null) {
                for (SuperVO vo : childlist) {
                    if (vo.getStatus() != EntityConst.DELETE) {
                        volist.add(vo);
                    }
                }
            }
            bill.setChildren(clazz, volist);
        }

    }

    private List<SuperVO> getList(Map<Class<?>, List<SuperVO>> index, Class<?> clazz) {
        List<SuperVO> list = null;
        if (index.containsKey(clazz)) {
            list = index.get(clazz);
        }
        else {
            list = new ArrayList<SuperVO>();
            index.put(clazz, list);
        }
        return list;
    }

    private Map<Class<?>, List<SuperVO>> group(AbstractMeBillVO bill, int status) {
        Map<Class<?>, List<SuperVO>> index = new HashMap<Class<?>, List<SuperVO>>();
        SuperVO head = bill.getHead();
        List<SuperVO> volist = this.getList(index, head.getClass());
        if (head.getStatus() == status) {
            volist.add(head);
        }

        Map<String, Class<?>> areaIndex = bill.getAreaNameIndex();
        Set<Map.Entry<String, Class<?>>> set = areaIndex.entrySet();
        for (Map.Entry<String, Class<?>> entry : set) {
            Class<?> clazz = entry.getValue();
            List<SuperVO> childlist = bill.getChildren(clazz);
            if (childlist != null) {
                volist = this.getList(index, clazz);
                for (SuperVO vo : childlist) {
                    if (vo.getStatus() == status) {
                        volist.add(vo);
                    }
                }
            }
        }
        return index;
    }

    private void setStatus(AbstractMeBillVO bill, int status) {
        SuperVO head = bill.getHead();
        head.setStatus(status);

        Map<String, Class<?>> areaIndex = bill.getAreaNameIndex();
        Set<Map.Entry<String, Class<?>>> set = areaIndex.entrySet();
        for (Map.Entry<String, Class<?>> entry : set) {
            Class<?> clazz = entry.getValue();
            List<SuperVO> childlist = bill.getChildren(clazz);
            if (childlist != null) {
                for (SuperVO vo : childlist) {
                    vo.setStatus(status);
                }
            }
        }
    }
}
